package com.yunze.system.index;

import com.alibaba.fastjson.JSON;
import com.rabbitmq.client.Channel;
import com.yunze.common.annotation.DataScope;
import com.yunze.common.core.redis.RedisCache;
import com.yunze.common.mapper.mysql.YzCardMapper;
import com.yunze.common.mapper.mysql.YzUserMapper;
import com.yunze.common.mapper.mysql.cwgl.CwglDepositInfoMapper;
import com.yunze.common.mapper.mysql.fhgl.FhglExpressInquiryMapper;
import com.yunze.common.mapper.mysql.fhgl.Ship.FhglShippingApplicationMapper;
import com.yunze.common.mapper.mysql.sysgl.YzAgentAssetDetailsMapper;
import com.yunze.common.mapper.mysql.sysgl.YzAssetDetailsMapper;
import com.yunze.common.mapper.mysql.warehouse.Administration.YzCkglInventorydetailsMapper;
import com.yunze.common.mapper.mysql.xsgl.Contract.YzXsglContractMapper;
import com.yunze.common.mapper.mysql.xsgl.customer.YzXsglCustomerMapper;
import com.yunze.common.utils.yunze.VeDate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 资费明细数据生成
 */
@Slf4j
@Component
public class AssetDetailsMq {


    @Resource
    private RedisCache redisCache;
    @Resource
    private YzAssetDetailsMapper yzAssetDetailsMapper;
    @Resource
    private YzUserMapper yzUserMapper;
    @Resource
    private YzCardMapper yzCardMapper;
    @Resource
    private YzXsglContractMapper yzXsglContractMapper;
    @Resource
    private YzAgentAssetDetailsMapper yzAgentAssetDetailsMapper;

    @Resource
    private FhglShippingApplicationMapper fhglShippingApplicationMapper;
    @Resource
    private YzXsglCustomerMapper yzXsglCustomerMapper;
    @Resource
    private FhglExpressInquiryMapper fhglExpressInquiryMapper;
    @Resource
    private CwglDepositInfoMapper cwglDepositInfoMapper;
    @Resource
    private YzCkglInventorydetailsMapper yzCkglInventorydetailsMapper;



    @RabbitHandler
    @RabbitListener(queues = "admin_AssetDetails_queue")
    private void Listener(String msg, Channel channel){
        ListeneCommonr(msg,true);
    }

    @RabbitHandler
    @RabbitListener(queues = "dlx_admin_AssetDetails_queue")
    private void DlxListener(String msg, Channel channel){
        ListeneCommonr(msg,true);
    }


    @RabbitHandler
    @RabbitListener(queues = "admin_AgentAssetDetails_queue")
    private void AgentListener(String msg, Channel channel){
        ListeneCommonr(msg,false);
    }


    @RabbitHandler
    @RabbitListener(queues = "dlx_admin_AgentAssetDetails_queue")
    private void DlxAgentListener(String msg, Channel channel){
        ListeneCommonr(msg,false);
    }

    /**
     * 监听公用
     * @param msg
     * @param internal
     */
    private void ListeneCommonr(String msg, Boolean internal){
        try {
            if (StringUtils.isEmpty(msg)) {
                return;
            }
            Map<String,Object> Pmap = JSON.parseObject(msg);
            String dept_id = Pmap.get("dept_id").toString();
            String prefix = "AssetDetails_queue";
            //执行前判断 redis 是否存在 执行数据 存在时 不执行
            String recordKey = prefix+":"+ dept_id;
            Object  isExecute = redisCache.getCacheObject(recordKey);
            if(isExecute==null){
                redisCache.setCacheObject(recordKey, msg, 3*60, TimeUnit.SECONDS);// 3分钟 缓存 避免 重复消费
                try {
                    DataGenerate(Pmap,recordKey,internal);
                }catch (Exception e){
                    log.error(">>admin_AssetDetails_queue  Generate 消费者:{}<<", e.getMessage());
                    redisCache.deleteObject(recordKey);//删除正在执行key
                }
           }
        } catch (Exception e) {
            log.error(">>错误 - 资产明细数据生成 消费者:{}<<", e.getMessage());
        }
    }




    private void DataGenerate(Map<String, Object> map, String recordKey,Boolean internal) {
        HashMap<String, Object> addAssetsMap = new HashMap<>();
        String dept_id = map.get("dept_id").toString();
        Map<String, Object> Adata = null;
        if(internal){
            Adata = yzAssetDetailsMapper.findExist(map);
        }else{
            Adata = yzAgentAssetDetailsMapper.findExist(map);
        }
        String record_date = map.get("record_date").toString();
        String day1 = record_date.substring(0,8)+"01";// 1号
        String year1 = record_date.substring(0,5)+"01-01";// 1月1号
        String sevenDaysAgo = VeDate.getNextDay(record_date, "-6");//获取七天前日期
        String sixMonthsAgo = "";
        try {
            sixMonthsAgo = VeDate.getFirstDayOfGivenMonth(VeDate.getMonthDate(record_date + " 00:00:00", -6), "yyyy-MM-dd");
        } catch (Exception e) {
            System.out.println("获取 sixMonthsAgo 异常" + e.getMessage());
        }

        if(Adata==null){
            Integer tobe_shipped = 0;//'待发货'
            Integer expressnotreceived = 0;//'快递未收'
            Double outstandingpayment = 0.0;//'未到款'
            Double have_Tailfunds = 0.0;//'有尾款'
            String batchM = "";//本月批号占比
            String batchY = "";//本年批号占比
            String commodityM = "";//本月商品占比
            String commodityY = "";//本年商品占比
            String contractM = "";//本月合同金额折线图
            String contractY = "";//本年合同金额折线图
            String signfor_expressdelivery = "";//快递签收状态
            String express_evaluation = "";//快递评价
            String shipment_status = "";//发货状态

            String amountofmoneylineM = "";//'本月合同金额饼装图-客户分类'
            String amountofmoneylineY = "";//'本年合同金额饼装图-客户分类'
            String warehousinglineM = "";//'本月入库商品折线图'
            String warehousinglineY = "";//'本年入库商品折线图'



            String SAN_CoID = null;
            if(!internal) {
                HashMap<String, Object> findCoIDMap = new HashMap<>();
                findCoIDMap.put("dept_id", dept_id);
                Map<String, Object> CustomerMap = yzXsglCustomerMapper.deptID(findCoIDMap);
                 SAN_CoID = CustomerMap != null && CustomerMap.get("id") != null ? CustomerMap.get("id").toString() : null;
            }else{
                SAN_CoID = "000";
            }
            if(SAN_CoID!=null){//如果当前系统企业没有绑定过 系统客户信息 不去 生成 【待发货】【快递未收】【未到款】【有尾款】【本月合同金额折线图】【本年合同金额折线图】【快递签收状态】【快递评价】【发货状态】
                HashMap<String, Object> tobeShippedMap = new HashMap<>();

                List<String> SAN_Delivery_Status = new ArrayList<>();
                SAN_Delivery_Status.add("1");//未发
                SAN_Delivery_Status.add("2");//未发全
                tobeShippedMap.put("SAN_Delivery_Status",SAN_Delivery_Status);
                if(!internal){
                    tobeShippedMap.put("SAN_CoID",SAN_CoID);
                }
                tobe_shipped = fhglShippingApplicationMapper.selMapCount(tobeShippedMap);
                tobe_shipped = tobe_shipped!=null?tobe_shipped:0;//【待发货】

                HashMap<String, Object> expressnotreceivedMap = new HashMap<>();
                List<String> EIY_Signing_Status = new ArrayList<>();
                EIY_Signing_Status.add("1");//未收
                if(!internal){
                    expressnotreceivedMap.put("cId",SAN_CoID);
                }
                expressnotreceived = fhglExpressInquiryMapper.selMapCount(expressnotreceivedMap);
                expressnotreceived = expressnotreceived!=null?expressnotreceived:0;//【快递未收】


                HashMap<String, Object> outstandingpaymentMap = new HashMap<>();
                outstandingpaymentMap.put("Dio_DsID", "1");//未到款  1
                if(!internal){
                    outstandingpaymentMap.put("cId",SAN_CoID);
                }
                String outstandingpaymentStr = cwglDepositInfoMapper.getSumDio_Unpaid(outstandingpaymentMap);
                outstandingpayment = outstandingpaymentStr!=null?Double.parseDouble(outstandingpaymentStr):0.0;//【未到款】

                HashMap<String, Object> have_TailfundsMap = new HashMap<>();
                have_TailfundsMap.put("Dio_DsID", "2");//有尾款 2
                if(!internal){
                    have_TailfundsMap.put("cId",SAN_CoID);
                }
                String have_TailfundsStr = cwglDepositInfoMapper.getSumDio_Unpaid(have_TailfundsMap);
                have_Tailfunds = have_TailfundsStr!=null?Double.parseDouble(have_TailfundsStr):0.0;//【有尾款】


                //===[统计图部分 开始]===

                //== 【本月 7天前-今天 合同金额折线图】

                Map<String, Object> Pmap_contractMList = new HashMap<>();
                Pmap_contractMList.put("timetype", "0");//合同日期
                Pmap_contractMList.put("staTime", sevenDaysAgo);//七天前
                Pmap_contractMList.put("endTime", record_date);
                Pmap_contractMList.put("FindType", "day");
                if(!internal){
                    Pmap_contractMList.put("c_fatId",SAN_CoID);
                }
                List<Map<String, Object>> contractMList = yzXsglContractMapper.getPolyline(Pmap_contractMList);
                contractM = getJsonStrLine(contractMList,"monthDay","count");


                // 【本年合同金额折线图】

                Map<String, Object> Pmap_contractYList = new HashMap<>();
                Pmap_contractYList.put("timetype", "0");//合同日期
                Pmap_contractYList.put("staTime", sixMonthsAgo);//六个月前
                Pmap_contractYList.put("endTime", record_date);
                Pmap_contractYList.put("FindType", "month");
                if(!internal){
                    Pmap_contractYList.put("c_fatId",SAN_CoID);
                }
                List<Map<String, Object>> contractYList = yzXsglContractMapper.getPolyline(Pmap_contractYList);
                contractY = getJsonStrLine(contractYList,"yearMonth","count");

                // 【快递签收状态】
                Map<String, Object> Pmap_signfor_expressdeliveryList = new HashMap<>();
                Pmap_signfor_expressdeliveryList.put("FindType","Signing");//分组依据
                Pmap_signfor_expressdeliveryList.put("timetype", "1");//发货日期
                Pmap_signfor_expressdeliveryList.put("staTime", day1);//当月第一天
                Pmap_signfor_expressdeliveryList.put("endTime", record_date);
                if(!internal){
                    Pmap_signfor_expressdeliveryList.put("cId",SAN_CoID);
                }
                List<Map<String, Object>> signfor_expressdeliveryList = fhglExpressInquiryMapper.groupCount(Pmap_signfor_expressdeliveryList);
                signfor_expressdelivery = getJsonStr(signfor_expressdeliveryList,"EIY_Signing_Status","count");


                // 【发货状态】
                Map<String, Object> Pmap_shipment_statusList = new HashMap<>();
                Pmap_shipment_statusList.put("FindType", "Delivery");//分组依据
                Pmap_shipment_statusList.put("timetype", "1");//发货日期
                Pmap_shipment_statusList.put("staTime", day1);//当月第一天
                Pmap_shipment_statusList.put("endTime", record_date);
                List<Map<String, Object>> shipment_statusList = fhglExpressInquiryMapper.groupCount(Pmap_shipment_statusList);
                shipment_status = getJsonStr(shipment_statusList,"SAN_Delivery_Status","count");


            }

            // 固定需要查询生成数据【'本月商品占比'】 【'本年商品占比'】
            // 【本月批号占比】
            Map<String, Object> Pmap_batchMList = new HashMap<>();
            Pmap_batchMList.put("timetype", "2");//发货日期
            Pmap_batchMList.put("staTime", day1);//当月第一天
            Pmap_batchMList.put("endTime", record_date);
            if(!internal){
                Pmap_batchMList.put("dept_id",dept_id);
            }
            List<Map<String, Object>> batchMList = yzCkglInventorydetailsMapper.groupByBatchNumber(Pmap_batchMList);
            batchM = getJsonStr(batchMList,"batchNumber","count");


            // 【本年批号占比】
            Map<String, Object> Pmap_batchYList = new HashMap<>();
            Pmap_batchYList.put("timetype", "2");//发货日期
            Pmap_batchYList.put("staTime", sixMonthsAgo);//六个月前
            Pmap_batchYList.put("endTime", record_date);
            if(!internal){
                Pmap_batchYList.put("dept_id",dept_id);
            }
            List<Map<String, Object>> batchYList = yzCkglInventorydetailsMapper.groupByBatchNumber(Pmap_batchYList);
            batchY = getJsonStr(batchYList,"batchNumber","count");


            // 【本月批号占比】
            Map<String, Object> Pmap_commodityMList = new HashMap<>();
            Pmap_commodityMList.put("timetype", "2");//发货日期
            Pmap_commodityMList.put("staTime", day1);//当月第一天
            Pmap_commodityMList.put("endTime", record_date);
            if(!internal){
                Pmap_commodityMList.put("dept_id",dept_id);
            }
            List<Map<String, Object>> commodityMList = yzCkglInventorydetailsMapper.groupByCyID(Pmap_commodityMList);
            commodityM = getJsonStr(commodityMList,"CSDS_CyID","count");

            // 【本年批号占比】
            Map<String, Object> Pmap_commodityYList = new HashMap<>();
            Pmap_commodityYList.put("timetype", "2");//发货日期
            Pmap_commodityYList.put("staTime", sixMonthsAgo);//六个月前
            Pmap_commodityYList.put("endTime", record_date);
            if(!internal){
                Pmap_commodityYList.put("dept_id",dept_id);
            }
            List<Map<String, Object>> commodityYList = yzCkglInventorydetailsMapper.groupByCyID(Pmap_commodityYList);
            commodityY = getJsonStr(commodityYList,"CSDS_CyID","count");



            if(internal){//内部管理需要生成
                // 【快递评价】
                Map<String, Object> Pmap_express_evaluationList = new HashMap<>();
                Pmap_express_evaluationList.put("FindType", "Evaluation");//分组依据
                Pmap_express_evaluationList.put("timetype", "1");//发货日期
                Pmap_express_evaluationList.put("staTime", day1);//当月第一天
                Pmap_express_evaluationList.put("endTime", record_date);
                List<Map<String, Object>> express_evaluationList = fhglExpressInquiryMapper.groupCount(Pmap_express_evaluationList);
                express_evaluation = getJsonStr(express_evaluationList,"EIY_Evaluation_Status","count");





                //本月合同金额饼装图-客户分类
                Map<String, Object> Pmap_amountofmoneylineMList = new HashMap<>();
                Pmap_amountofmoneylineMList.put("timetype", "0");//合同日期
                Pmap_amountofmoneylineMList.put("staTime", day1);//当月第一天
                Pmap_amountofmoneylineMList.put("endTime", record_date);
                Pmap_amountofmoneylineMList.put("FindType", "cId");
                List<Map<String, Object>> amountofmoneylineMList = yzXsglContractMapper.getPolyline(Pmap_amountofmoneylineMList);
                amountofmoneylineM = getJsonStr(amountofmoneylineMList,"c_name","sumAmount");

                //本年合同金额饼装图-客户分类
                Map<String, Object> Pmap_amountofmoneylineYList = new HashMap<>();
                Pmap_amountofmoneylineYList.put("timetype", "0");//合同日期
                Pmap_amountofmoneylineYList.put("staTime",year1 );//记录那年 1月1号
                Pmap_amountofmoneylineYList.put("endTime", record_date);
                Pmap_amountofmoneylineYList.put("FindType", "cId");
                List<Map<String, Object>> amountofmoneylineYList = yzXsglContractMapper.getPolyline(Pmap_amountofmoneylineYList);
                amountofmoneylineY = getJsonStr(amountofmoneylineYList,"c_name","sumAmount");


                //本月入库商品折线图
                Map<String, Object> Pmap_warehousinglineMList = new HashMap<>();
                Pmap_warehousinglineMList.put("FindType", "day");
                Pmap_warehousinglineMList.put("timetype", "2");//发货日期
                Pmap_warehousinglineMList.put("staTime", sevenDaysAgo);//七天前
                Pmap_warehousinglineMList.put("endTime", record_date);
                List<Map<String, Object>> warehousinglineMList = yzCkglInventorydetailsMapper.groupByCyID(Pmap_warehousinglineMList);
                warehousinglineM = getJsonStrLine(warehousinglineMList,"CSDS_CyID","count");

                //本年入库商品折线图
                Map<String, Object> Pmap_warehousinglineYList = new HashMap<>();
                Pmap_warehousinglineYList.put("FindType", "day");
                Pmap_warehousinglineYList.put("timetype", "2");//发货日期
                Pmap_warehousinglineYList.put("staTime", sixMonthsAgo);//六个月前
                Pmap_warehousinglineYList.put("endTime", record_date);
                List<Map<String, Object>> warehousinglineYList = yzCkglInventorydetailsMapper.groupByCyID(Pmap_warehousinglineYList);
                warehousinglineY = getJsonStrLine(warehousinglineYList,"CSDS_CyID","count");

                addAssetsMap.put("amountofmoneylineM",amountofmoneylineM);
                addAssetsMap.put("amountofmoneylineY",amountofmoneylineY);
                addAssetsMap.put("warehousinglineM",warehousinglineM);
                addAssetsMap.put("warehousinglineY",warehousinglineY);
            }



            addAssetsMap.put("tobe_shipped",tobe_shipped);
            addAssetsMap.put("expressnotreceived",expressnotreceived);
            addAssetsMap.put("outstandingpayment",outstandingpayment);
            addAssetsMap.put("have_Tailfunds",have_Tailfunds);
            addAssetsMap.put("batchM",batchM);
            addAssetsMap.put("batchY",batchY);
            addAssetsMap.put("commodityM",commodityM);
            addAssetsMap.put("commodityY",commodityY);
            addAssetsMap.put("contractM",contractM);
            addAssetsMap.put("contractY",contractY);
            addAssetsMap.put("express_evaluation",express_evaluation);
            addAssetsMap.put("signfor_expressdelivery",signfor_expressdelivery);
            addAssetsMap.put("shipment_status",shipment_status);
            addAssetsMap.put("record_date",record_date);
            addAssetsMap.put("dept_id",dept_id);





            if(internal){
                yzAssetDetailsMapper.addAssets(addAssetsMap);
            }else{
                yzAgentAssetDetailsMapper.addAssets(addAssetsMap);
            }

        }else{
            System.out.println("数据已生成");
            log.info(" 资产明细已生成，无需重复生产 {}"+JSON.toJSONString(map));
        }
    }


    /**
     * 读取 dbList 打包成JSON 字符串
     * @param dbList
     * @param nameKey
     * @param valueKey
     * @return
     */
    public String getJsonStr(List<Map<String, Object>> dbList,String nameKey,String valueKey){
        String rJsonStr = "";
        if(dbList!=null){
            List<Map<String, Object>> dataList = new ArrayList<>();
            for (int j = 0; j < dbList.size(); j++) {
                Map<String, Object> Count_obj = dbList.get(j);
                Map<String, Object> data = new HashMap<>();
                Object name =  Count_obj.get(nameKey);
                Object value =  Count_obj.get(valueKey);
                if(name!=null && name.toString().length()>0){
                    data.put("name",name);
                    data.put("value",value);
                }
                dataList.add(data);
            }
            rJsonStr = dataList!=null?JSON.toJSONString(dataList):rJsonStr;
        }
        return rJsonStr;
    }


    /**
     * 获取现行统计图数据
     * @param dbList
     * @param nameKey
     * @param valueKey
     * @return
     */
    public String getJsonStrLine(List<Map<String, Object>> dbList,String nameKey,String valueKey){
        String rJsonStr = "";
        Map<String, Object> line_Info = new HashMap<>();
        if (dbList != null && dbList.size() > 0) {
            Map<String, Object> mapObj = new HashMap<>();
            ArrayList dataArr = new ArrayList();//数据列
            ArrayList xAxis = new ArrayList();//X 轴
            for (int i = 0; i < dbList.size(); i++) {
                Map<String, Object> obj = dbList.get(i);
                String value = obj.get(valueKey) != null ? obj.get(valueKey).toString() : "0";
                dataArr.add(value);
                xAxis.add(obj.get(nameKey));
            }
            mapObj.put("dataArr", dataArr);
            line_Info.put("mapObj", mapObj);
            line_Info.put("xAxis", xAxis);
        }
         rJsonStr = line_Info.get("xAxis")!=null?JSON.toJSONString(line_Info):rJsonStr;
        return rJsonStr;
    }






    @DataScope(deptAlias = "d" , userAlias = "u" , isMap=true)
    public List<String> getUserID(Map<String, Object> map) {
        return yzUserMapper.getUserID(map);
    }


    /**
     * 查询部门管理数据
     */
    @DataScope(deptAlias = "d", isMap=true)
    public Integer selectDeptListCount(Map<String, Object> map)
    {
        return yzUserMapper.selectDeptListCount(map);
    }

}
